#ifndef COOLPOOL_SIMULATION_CUE_H_
#define COOLPOOL_SIMULATION_CUE_H_

#include <GL/freeglut.h>
#include <CPMath.h>
#include <Vector3D.h>

#include "Ball.h"

namespace coolpool
{
	// Simple cue for adding impulse force to selected ball.
	// Its working just in the plane  parallel to the x,z plane.
	class Cue
	{
	public:

		Cue(Ball * ball, double min_dist, double max_dist, double spring_stiffnes, GLuint texture);
		virtual ~Cue();

		// Renders the cues as a simple triangle.
		void render();

		// Updates the new position of the end.
		// Input is should from the OpenGL picking method.
		inline void updatePosition(const math_tools::Vector3D & new_position)
		{
			math_tools::Vector3D new_pos_copy = new_position;
			math_tools::Vector3D ball_pos = ball_->getCenterOfMassLocation();
			new_pos_copy.setY(ball_pos.getY());
			math_tools::Vector3D rel_position = new_pos_copy - ball_pos;

			// Force min and max bounds.
			double mag = rel_position.mag();
			if (mag < min_dist_)
				rel_position *= min_dist_ / mag;
			if (mag > max_dist_)
				rel_position *= max_dist_ / mag;
			position_ = rel_position;
		}

		// Hits the ball with a spring like force.
		inline void hit()
		{
			double mag = position_.mag();
			if (mag > min_dist_)
			{
				ball_->setLinearMomentum(-position_ * spring_stiffnes_);
				ball_->setAngularMomentum(math_tools::Vector3D(0.0, 0.0, 0.0));
			}
			resetDistance();
		}

		// Resets the distance of the cue end to the minimum.
		inline void resetDistance()
		{
			position_ *= min_dist_ / position_.mag();
		}

		// Getters:
		inline const math_tools::Vector3D & getLookAtPosition()
		{
			return ball_->getCenterOfMassLocation();
		}

	private:

		// Ball with which the cue will interact.
		Ball * ball_;

		// Maximal allowed distance of the cue end.
		double max_dist_;

		// Minimal allowed distance of the cue end.
		double min_dist_;

		// Current relative position of the cue ball.
		math_tools::Vector3D position_;

		// Hooks coefficient of stiffness.
		double spring_stiffnes_;

		// Triangle texture
		GLuint texture_;
	};
}

#endif
